
/**输出的时间结构体 */
export class TimeData {
    public hour: number;
    public minute: number;
    public second: number;
}

/**时间工具类 */
export class TimeUtils {
    public static readonly str_second = "second"
    public static readonly str_minute = "minute"
    public static readonly str_hour = "hour"
    public static readonly str_day = "day"
    public static readonly str_ms = "millisecond"

    public static getToday(){
        let todayDate = new Date();
        return todayDate.toLocaleDateString().replace(/\//g,"-");
    }

    /**转换成Date类 */
    public static getDate(time: number | string | Date): Date {
        let date = null;
        if (time instanceof Date) {
            date = time
        } else {
            date = new Date(time)
        }
        return date;
    }
    /**转换成时间戳 */
    public static getTime(date: number | string | Date): string {
        let time = null;
        if (date instanceof Date) {
            time = date.getTime();
        } else {
            time = new Date(time).getTime();
        }
        return time;
    }

    /**是否新一天 */
    public static isNewDay(compare: Date, now: Date): boolean {
        if (!compare || !now) {
            throw new Error("have one date is wrong");
        }
        if (now.getFullYear() !== compare.getFullYear() ||
            now.getMonth() !== compare.getMonth() ||
            now.getDate() !== compare.getDate()) {
            return true;
        }
        return false;
    }

    /**是否新的一周 */
    public static isNewWeek(beforeDate: number | string | Date, lateDate: number | string | Date) {
        let weekDiff = this.compareWeekByDate(beforeDate, lateDate)
        if (weekDiff > 0) {
            return true
        }
        return false
    }

    public static moreThanTime(compare: Date, now: Date, second: number) {
        return (now.getTime() - compare.getTime()) >= second * 1000;
    }

    /**格式化当前日期 年-月-日 时:分:秒 */
    public static formatNowDate(): string {
        const date = new Date();
        return this.formatDate(date.getTime());
    }

    /**格式化日期 年-月-日 时:分:秒 */
    public static formatDate(dateStr: string | number | Date) {
        const date: Date = this.getDate(dateStr);
        //年份
        const year: number = date.getFullYear();
        //月份下标是0-11
        const months: any = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1);
        //具体的天数
        const day: any = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
        //小时
        const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
        //分钟
        const minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
        //秒
        const seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
        //返回数据格式
        return year + '-' + months + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
    }



    /**
     * @description 秒数转 时分秒
     */
    public static secondsToHMS(seconds: number, filter_hour: boolean = false, zero_hour : boolean = true) {
        let real_seconds = Math.floor(seconds % 60);
        let minutes = Math.floor((seconds / 60) % 60);
        let hours = Math.floor(seconds / 3600);
        let str_seconds = real_seconds < 10 ? `0${real_seconds}` : real_seconds;
        let str_minutes = minutes < 10 ? `0${minutes}` : minutes;
        let str_hours = hours < 10 ? `${zero_hour? "0" : ""}${hours}` : hours;
        if (filter_hour && hours === 0) {
            return `${str_minutes}:${str_seconds}`;
        }
        return `${str_hours}:${str_minutes}:${str_seconds}`;
    }


    /**
     * @description 秒数转 时分
     */
    public static secondsToHM(seconds: number) {
        let minutes = Math.floor((seconds / 60) % 60);
        let hours = Math.floor(seconds / 3600);
        let str_minutes = minutes < 10 ? `0${minutes}` : minutes;
        let str_hours = hours < 10 ? `0${hours}` : hours;

        return `${str_hours}:${str_minutes}`;
    }

    
    /**
     * @description 秒数转 分秒
     */
    public static secondsToMS(seconds: number) {
        let real_seconds = Math.floor(seconds % 60);
        let minutes = Math.floor((seconds / 60));
        let str_seconds = real_seconds < 10 ? `0${real_seconds}` : real_seconds;
        let str_minutes = minutes < 10 ? `0${minutes}` : minutes;
        return `${str_minutes}:${str_seconds}`;
    }


    /*
    * 比较时间大小
    * time1>time2 return 1
    * time1<time2 return -1
    * time1==time2 return 0
    */
    public static compareTime(time1: string, time2: string): number {
        if (Date.parse(time1.replace(/-/g, "/")) > Date.parse(time2.replace(/-/g, "/"))) {
            return 1;
        } else if (Date.parse(time1.replace(/-/g, "/")) < Date.parse(time2.replace(/-/g, "/"))) {
            return -1;
        } else if (Date.parse(time1.replace(/-/g, "/")) == Date.parse(time2.replace(/-/g, "/"))) {
            return 0;
        }
        return 0
    }

    /**是否闰年 */
    public static isLeapYear(year: number): boolean {
        return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0)
    }

    /**获取某个月的天数，从0开始 */
    public static getDaysOfMonth(year: number, month: number) {
        return [31, (this.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    }
    public static getDaysOfMonth2(year: number, month: number) {
        // 将天置为0，会获取其上个月的最后一天
        month = month + 1;
        let date = new Date(year, month, 0);
        return date.getDate();
    }
    /*
     *距离现在几天的日期：负数表示今天之前的日期，0表示今天，整数表示未来的日期
     * 如-1表示昨天的日期，0表示今天，2表示后天
     */
    public static fromToday(days: number): string {
        let today = new Date();
        today.setDate(today.getDate() + days);
        let date = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate();
        return date;
    }

    /**
     * 计算一个日期是当年的第几天
     * @param {Object} date
     */
    public static dayOfTheYear(date: string | number | Date): number {
        let obj = this.getDate(date);
        let year = obj.getFullYear();
        let month = obj.getMonth(); //从0开始
        let days = obj.getDate();
        let daysArr = [31, (this.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        for (var i = 0; i < month; i++) {
            days += daysArr[i];
        }
        return days;
    }

    /**获得时区名和值 */
    public static getZoneNameValue(date: Date) {
        date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
        let arr = date.toString().match(/([A-Z]+)([-+]\d+:?\d+)/);
        let obj = {
            'name': arr[1],
            'value': arr[2]
        };
        return obj;
    }

    /**返回星期几 */
    public static getDayInWeek(dateTime: number | string | Date) {
        // let dayList = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六",]
        let dayList = [7, 1, 2, 3, 4, 5, 6]
        let date = this.getDate(dateTime)
        let week = date.getDay()
        return dayList[week]
    }

    /**增加时间 */
    public static plusTime(time: number | string | Date, plus: number, diffType: string): Date {
        time = this.getDate(time);
        let date = new Date();
        switch (diffType) {
            case this.str_second:
                date.setSeconds(date.getSeconds() + plus)
                break;
            case this.str_minute:
                date.setMinutes(date.getMinutes() + plus)
                break;
            case this.str_hour:
                date.setHours(date.getHours() + plus)
                break;
            case this.str_day:
                date.setDate(date.getDate() + plus)
                break;
            case this.str_ms:
                date.setDate(date.getTime() + plus)
                break;
            default:
                break;
        }
        return date
    }

    /**计算两个时间的时间相差 */
    public static getDateDiff(startTime: number | string | Date, endTime: number | string | Date, diffType: string = "day"): number {
        //将计算间隔类性字符转换为小写
        diffType = diffType.toLowerCase();

        let sTime = this.getDate(startTime); //开始时间
        let eTime = this.getDate(endTime); //结束时间
        //作为除数的数字
        let timeType = 1;
        switch (diffType) {
            case this.str_second:
                timeType = 1000;
                break;
            case this.str_minute:
                timeType = 1000 * 60;
                break;
            case this.str_hour:
                timeType = 1000 * 3600;
                break;
            case this.str_day:
                timeType = 1000 * 3600 * 24;
                break;
            case this.str_ms:
                timeType = 1;
                break;
            default:
                break;
        }
        let diff = Math.floor((eTime.getTime() - sTime.getTime()) / timeType);
        return diff

    }

    /**计算两个日期之间相差几周 */
    public static compareWeekByDate(beforeDate: number | string | Date, lateDate: number | string | Date) {
        let diffDays = this.getDateDiff(beforeDate, lateDate)
        let beforeDateInWeek = this.getDayInWeek(beforeDate)
        // let week = diffDays / 7
        // let day = diffDays % 7 + beforeDateInWeek
        // if (day > 7) {
        //     week ++
        //     day = day % 7
        // }

        let day = beforeDateInWeek
        let dayInWeek = diffDays + day
        // let weekNum = 0
        // while (dayInWeek > 7) {
        //     dayInWeek -= 7
        //     weekNum++
        // }
        let weekNum = Math.floor(dayInWeek / 7)
        dayInWeek = Math.floor(dayInWeek % 7)
        return weekNum
    }
    /**检查时间是否在区间范围 默认当前时间 */
    public static checkTimeInRange(startTime: number | string | Date, endTime: number | string | Date, time: number | string | Date) {
        let start = this.getTime(startTime);// new Date(startTime).getTime()
        let end = this.getTime(endTime);//  new Date(endTime).getTime()
        let cur = this.getTime(time);// new Date(time).getTime()
        if (cur >= start && cur <= end) {
            return true
        }
        return false
    }

    /**根据当前时间,计算周一和周七的日期 */
    public static getWeekRangeByTime(time: number | string) {
        let day = this.getDayInWeek(time)
        let beforeDay = 1 - day
        let endDay = beforeDay + 6

        let before = this.fromToday(beforeDay)
        let end = this.fromToday(endDay)

        return {
            before: before,
            end: end,
        }
    }

    /**根据总秒数,生成天,时,分,秒的结构 */
    public static getTimeDataBySecond(second: number): TimeData {
        let data = new TimeData();
        data.second = Math.round(second);// 秒
        data.minute = 0;// 分
        data.hour = 0;// 小时
        if (data.second > 60) {//如果秒数大于60，将秒数转换成整数
            //获取分钟，除以60取整数，得到整数分钟
            data.minute = Math.floor(data.second / 60);
            //获取秒数，秒数取佘，得到整数秒数
            data.second = data.second % 60;
            //如果分钟大于60，将分钟转换成小时
            if (data.minute > 60) {
                //获取小时，获取分钟除以60，得到整数小时
                data.hour = Math.floor(data.minute / 60);
                //获取小时后取佘的分，获取分钟除以60取佘的分
                data.minute = data.minute % 60;
            }
        }

        return data;
    }

    public static timestampToMDHM(timestamp: string): string {
        let dateTime: string = "";
        let date = new Date();
        date.setTime(Number(timestamp));
        let hours = date.getHours();
        let str_hours = hours < 10 ? `0${hours}` : hours;
        let minutes = date.getMinutes();
        let str_minutes = minutes < 10 ? `0${minutes}` : minutes;
        dateTime = (date.getMonth() + 1) + "/" + date.getDate() + " " + str_hours + ":" + str_minutes; // 月/日 时：分
        return dateTime;
    }

    public static timestampToYMD(timestamp: string | number): string {
        let dateTime: string = "";
        let date = new Date();
        date.setTime(Number(timestamp));
        dateTime = date.getFullYear() + (date.getMonth() + 1) + "" + date.getDate(); // 年 月/日
        return dateTime;
    }
T
    /**
     * 计算明天指定时间的时间
     * @param hours 时
     * @param minutes 分
     * @param seconds 秒
     */
    public static getTomorrowDate(hours:number, minutes: number = 0, seconds: number = 0):Date{
        let now = new Date();
        return this.formatYMDtoDate(now.getFullYear(), now.getMonth(), now.getDate()+1,hours,minutes,seconds);
    }
    /**
     * 计算今天指定时间的时间
     * @param hours 时
     * @param minutes 分
     * @param seconds 秒
     */
    public static getTotayDate(hours:number, minutes: number = 0, seconds: number = 0):Date{
        let now = new Date();
        let year = now.getUTCFullYear();
        let month = now.getMonth()+1;
        let day = now.getDate();
        return this.formatYMDtoDate(now.getFullYear(), now.getMonth(), now.getDate(),hours,minutes,seconds);
    }
    /**计算指定时间的时间 */
    public static formatYMDtoDate(year:number,month:number,day:number,hours:number = 0,minutes:number = 0,seconds:number = 0):Date{
        return new Date(year, month,day,hours,minutes,seconds);
    }

}